package inf3791.calendarsystem.shared;

import eu.mpower.framework.security.types.soap.LoginStatus;
import eu.mpower.framework.security.types.soap.SecurityToken;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Zhang Wei
 */
public class Authenticator implements AuthenticationProvider {

    private SecurityToken sectoken;
    private Thread loginThread;

    public class AuthenticationError extends Exception {
    }

    public synchronized void startLogin(final String username, final String password) {
        if (loginThread != null) {
            throw new RuntimeException("Login already started");
        }

        loginThread = new Thread() {
            @Override
            public void run() {
                try {
                    login(username, password);
                } catch (AuthenticationError ex) {
                    Logger.getLogger(Authenticator.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        };
    }

    public synchronized void login(String username, String password) throws AuthenticationError {

        LoginStatus loginStatus = authenticateUserPass(username, password);

        if (loginStatus.getStatus().getResult() == 0) {
            sectoken = loginStatus.getSecurityToken();
            for (AuthenticationChangedListener acl : listeners) {
                acl.securityTokenChanged(loginStatus.getSecurityToken());
            }

        } else {
            sectoken = null;
            for (AuthenticationChangedListener acl : listeners) {
                acl.securityTokenVoided();
            }

            throw new AuthenticationError();
        }
    }

    public synchronized void logout() {

        loginThread = null;

        for (AuthenticationChangedListener acl : listeners) {
            acl.securityTokenVoided();
        }
    }

    private static LoginStatus authenticateUserPass(java.lang.String username, java.lang.String password) {
        eu.mpower.framework.security.authentication.soap.AuthenticationWServiceService service = new eu.mpower.framework.security.authentication.soap.AuthenticationWServiceService();
        eu.mpower.framework.security.authentication.soap.PortTypeAuthenticationWService port = service.getAuthenticationWServicePort();
        return port.authenticateUserPass(username, password);
    }
    private List<AuthenticationChangedListener> listeners = new LinkedList<>();

    @Override
    public void addAuthenticationChangedListener(AuthenticationChangedListener acl) {
        if (sectoken != null) {
            acl.securityTokenChanged(sectoken);
        } else {
            acl.securityTokenVoided();
        }
        listeners.add(acl);
    }

    @Override
    public void removeAuthenticationChangedListener(AuthenticationChangedListener acl) {
        listeners.remove(acl);
    }
}
